module mxu_rmb_rdgen (
    input logic             clk,
    input logic             rst_n,
          mxu_cfg_if.rmb_in mxu_cfg,
          rmb_rd_req_if.out mxu_rmb_rd_req
);

    logic cfg_rdy, cfg_vld;
    logic        last_req_in_instr;
    logic [15:0] rmb_base_addr;

    assign cfg_vld       = ~cfg_rdy;
    assign rmb_base_addr = mxu_cfg.rmb_addr;

    always_ff @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            cfg_rdy <= 1'b1;
        end else if (cfg_rdy == 1'b0) begin
            if (lst_req_in_instr && mxu_rmb_rd_req.vld && mxu_rmb_rd_req.rdy) begin
                cfg_rdy <= 1'b1;
            end
        end else begin
            if (mxu_cfg.vld && mxu_cfg.rdy) begin
                cfg_rdy <= 1'b0;
            end
        end
    end

    logic [15:0] slice_n1;
    logic [15:0] slice_m1;
    logic [15:0] slice_k1;
    logic [15:0] m1_idx;
    logic [15:0] n1_idx;
    logic [15:0] k1_idx;

    assign slice_n1 = (mxu_cfg.slice_n + `N0 - 1) / `N0;
    assign slice_m1 = (mxu_cfg.slice_m + `M0 - 1) / `M0;
    assign slice_k1 = mxu_cfg.slice_k1;
    always_ff @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            m1_idx <= 16'd0;
            n1_idx <= 16'd0;
            k1_idx <= 16'd0;
        end else if (mxu_rmb_rd_req.vld && mxu_rmb_rd_req.rdy) begin
            if (lst_req_in_instr) begin
                m1_idx <= 16'd0;
                n1_idx <= 16'd0;
                k1_idx <= 16'd0;
            end else if (k1_idx == (slice_k1 - 1)) begin
                k1_idx <= 16'd0;
                if (n1_idx == (slice_n1 - 1)) begin
                    n1_idx <= 16'd0;
                    m1_idx <= m1_idx + 16'd1;
                end else begin
                    n1_idx <= n1_idx + 16'd1;
                end
            end else begin
                k1_idx <= k1_idx + 16'd1;
            end
        end
    end

    logic [15:0] rmb_addr;
    assign rmb_addr = rmb_base_addr + (n1_idx * slice_k1 + k1_idx) * `N0 * `K0_Byte;
    assign mxu_rmb_rd_req.rmb_addr = rmb_addr;
    assign mxu_rmb_rd_req.vld = cfg_vld;
    assign last_req_in_instr = (m1_idx == (slice_m1 - 1)) && (n1_idx == (slice_n1 - 1)) && (k1_idx == (slice_k1 - 1));

endmodule
